﻿#region File Header
//-----------------------------------------------------------------------------
// Bricks' Bane
//
// Copyright (C) 2010 Julien Villers
// This program is distributed under the terms of the 
// GNU Lesser General Public License (LGPL).
// See Docs/lgpl.txt and Docs/gpl.txt
//-----------------------------------------------------------------------------
#endregion

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SibLib.Entities;
using SibLib.Render;
using SibLib.Render.Primitives3D;

namespace BricksBane.Entities
{
    /// <summary>
    /// Base class for all bricks.
    /// Instances of this class are standard bricks, destroyed by N ball impacts.
    /// </summary>
    sealed class Brick : GameplayObject, ICollideable2D
    {
        public enum E_Types
        {
            Basic = 0,
            Multiple,
            Unbreakable,
            Nitro,
        };

        #region Members
        private Rectangle m_BoundingBox;
        private Vector2 m_Size;
        //private BasicModel m_Model;
        private static GeometricPrimitive m_Primitive = null;
        private Matrix m_WorldMatrix;
        #endregion

        #region Properties
        public Vector2 Size
        {
            get { return m_Size; }
            set { m_Size = value; }
        }
        public Color Color
        {
            get;
            set;
        }
        public int HitPoints
        {
            get;
            set;
        }
        public Drop Drop
        {
            get;
            set;
        }
        public E_Types Type
        {
            get;
            set;
        }
        #endregion

        #region Setup

        public Brick() :
            base()
        {    
        }

        public override void Initialize()
        {
            /*m_Model = new BasicModel("Models/Brick1");
            m_Model.Position = new Vector3(Position, 0.0f);
            m_Model.Color = Color;
            m_Model.SceneInfo = GameplayScreen.Instance.SceneInfo;
            m_Model.Scale = 10.0f;*/

            m_WorldMatrix = Matrix.CreateRotationZ(MathHelper.PiOver2) * Matrix.CreateTranslation(new Vector3(m_Position, 0.0f));

            m_BoundingBox = new Rectangle((int)(Position.X - (Size.X / 2.0f)), (int)(Position.Y - (Size.Y / 2.0f)), (int)Size.X, (int)Size.Y);

            base.Initialize();            
        }

        protected override void LoadContent()
        {
            if (m_Primitive == null)
            {
                GraphicsDevice device = GameplayScreen.Instance.GraphicsDevice;
                m_Primitive = new CylinderPrimitive(device, m_Size.X, m_Size.Y, 8);
                //m_Primitive = new RoundedCylinderPrimitive(device, m_Size.X, m_Size.Y, 8);
            }

            //ContentManager content = GameplayScreen.Instance.Content;
            //m_Model.LoadContent(content);
        }

        #endregion

        #region Update

        public override void Update(float timeFactor)
        {

        }

        #endregion

        #region Collision

        public Rectangle GetBoundingBox()
        {
            return m_BoundingBox;
        }

        #endregion

        #region Render

        private static readonly string[] NUMBERS =
        {
            "0",
            "1",
            "2",
            "3",
            "4",
            "5",
            "6",
            "7",
            "8",
            "9",
        };

        public override void Draw(float timeFactor)
        {
            //m_Model.Draw(timeFactor);

            GameplayScreen screen = GameplayScreen.Instance;

            SceneInfo info = screen.SceneInfo;
            m_Primitive.Draw(m_WorldMatrix, info.ViewMatrix, info.ProjectionMatrix, Color);

            if (Type == E_Types.Multiple)
            {
                SpriteBatch spriteBatch = screen.SpriteBatch;
                SpriteFont font = screen.SpriteFontGame;
                Vector2 pos = m_Position - (font.MeasureString(NUMBERS[HitPoints]) / 2.0f) + new Vector2(0, 2);
                spriteBatch.Begin();
                spriteBatch.DrawString(font, NUMBERS[HitPoints], pos + Vector2.One, Color.Black);
                spriteBatch.DrawString(font, NUMBERS[HitPoints], pos - Vector2.One, Color.Black);
                spriteBatch.DrawString(font, NUMBERS[HitPoints], pos + new Vector2(1, -1), Color.Black);
                spriteBatch.DrawString(font, NUMBERS[HitPoints], pos + new Vector2(-1, 1), Color.Black);
                spriteBatch.DrawString(font, NUMBERS[HitPoints], pos, Color.White);
                spriteBatch.End();
            }
        }

        #endregion

        #region Brick API

        public bool OnBallHit(Ball ball)
        {
            if (Type == E_Types.Unbreakable)
                return false;

            if (HitPoints > 0)
            {
                if (ball.Type == Ball.E_Types.Superball)
                    HitPoints -= 3;
                else
                    HitPoints--;
                if (HitPoints <= 0)
                {
                    OnDestroyed();
                    return true;
                }
            }
            return false;
        }

        public bool OnBulletHit(Bullet bullet)
        {
            if (HitPoints > 0)
            {
                HitPoints--;        // TODO: tuning
                if (HitPoints == 0)
                {
                    OnDestroyed();
                    return true;
                }
            }
            return false;
        }

        public bool OnExplosionHit()
        {
            if (HitPoints > 0)
            {
                HitPoints--;        // TODO: tuning
                if (HitPoints == 0)
                {
                    OnDestroyed();
                    return true;
                }
            }
            return false;
        }

        private void OnDestroyed()
        {
            IsActive = false;
            // TODO: VFX

            GameplayScreen.Instance.OnBrickDestroyed(this);
        }

        #endregion
    }
}
